1 // spline equation courtesy Andeeee's CRSpline (http://forum.unity3d.com/threads/32954-Waypoints-and-constant-variable-speed-problems?p=213942&viewfull=1#post213942)
2
3 using
UnityEngine;
4 using
System.IO;
5 using
System.Collections;
6 using
System.Collections.Generic;
7
8
9 public
class GoSpline
10 {
11     
public int currentSegment { get; private set; }
12     
public bool isClosed { get; private set; }
13     
public GoSplineType splineType { get; private set; }
14     
15     
// used by the visual path editor
16     
public List<Vector3> nodes { get { return _solver.nodes; } }
17
18     
private bool _isReversed; // internal flag that lets us know if our nodes are reversed or not
19     
private AbstractGoSplineSolver _solver;
20     
21     
22     
// default constructor
23     
public GoSpline( List<Vector3> nodes, bool useStraightLines = false )
24     {
25         
// determine spline type and solver based on number of nodes
26         
if( useStraightLines || nodes.Count == 2 )
27         {
28             splineType = GoSplineType.StraightLine;
29             _solver =
new GoSplineStraightLineSolver( nodes );
30         }
31         
else if( nodes.Count == 3 )
32         {
33             splineType = GoSplineType.QuadraticBezier;
34             _solver =
new GoSplineQuadraticBezierSolver( nodes );
35         }
36         
else if( nodes.Count == 4 )
37         {
38             splineType = GoSplineType.CubicBezier;
39             _solver =
new GoSplineCubicBezierSolver( nodes );
40         }
41         
else
42         {
43             splineType = GoSplineType.CatmullRom;
44             _solver =
new GoSplineCatmullRomSolver( nodes );
45         }
46     }
47     
48     
49     
public GoSpline( Vector3[] nodes, bool useStraightLines = false ) : this( new List<Vector3>( nodes ), useStraightLines )
50     {}
51     
52     
53     
public GoSpline( string pathAssetName, bool useStraightLines = false ) : this( nodeListFromAsset( pathAssetName ), useStraightLines )
54     {}

55     
56     
57     ///
<summary>
58     ///
helper to get a node list from an asset created with the visual editor
59     ///
</summary>
60     
private static List<Vector3> nodeListFromAsset( string pathAssetName )
61     {
62         
if( Application.platform == RuntimePlatform.OSXWebPlayer || Application.platform == RuntimePlatform.WindowsWebPlayer )
63         {
64             Debug.LogError(
"The Web Player does not support loading files from disk." );
65             
return null;
66         }
67
68         
69         
var path = string.Empty;
70         
if( !pathAssetName.EndsWith( ".asset" ) )
71             pathAssetName +=
".asset";
72         
73         
74         
if( Application.platform == RuntimePlatform.Android )
75         {
76             path = Path.Combine(
"jar:file://" + Application.dataPath + "!/assets/", pathAssetName );
77         
78             WWW loadAsset =
new WWW( path );
79             
while( !loadAsset.isDone ) { } // maybe make a safety check here
80             
81             
return bytesToVector3List( loadAsset.bytes );
82         }
83         
else if( Application.platform == RuntimePlatform.IPhonePlayer )
84         {
85             
// at runtime on iOS, we load from the dataPath
86             path = Path.Combine( Path.Combine( Application.dataPath,
"Raw" ), pathAssetName );
87         }
88         
else
89         {
90             
// in the editor we default to looking in the StreamingAssets folder
91             path = Path.Combine( Path.Combine( Application.dataPath,
"StreamingAssets" ), pathAssetName );
92         }
93         
94 #
if UNITY_WEBPLAYER || NETFX_CORE || UNITY_WINRT
95         
// it isnt possible to get here but the compiler needs it to be here anyway
96         
return null;
97 #
else
98         
var bytes = File.ReadAllBytes( path );
99         
return bytesToVector3List( bytes );
100 #endif
101     }

102     
103     
104     ///
<summary>
105     ///
helper to get a node list from an asset created with the visual editor
106     ///
</summary>
107     
public static List<Vector3> bytesToVector3List( byte[] bytes )
108     {
109         
var vecs = new List<Vector3>();
110         
for( var i = 0; i < bytes.Length; i += 12 )
111         {
112             
var newVec = new Vector3( System.BitConverter.ToSingle( bytes, i ), System.BitConverter.ToSingle( bytes, i + 4 ), System.BitConverter.ToSingle( bytes, i + 8 ) );
113             vecs.Add( newVec );
114         }
115         
116         
return vecs;
117     }

118     
119     
120     ///
<summary>
121     ///
gets the last node. used to setup relative tweens
122     ///
</summary>
123     
public Vector3 getLastNode()
124     {
125         
return _solver.nodes[_solver.nodes.Count];
126     }

127     
128     
129     ///
<summary>
130     ///
responsible for calculating total length, segmentStartLocations and segmentDistances
131     ///
</summary>
132     
public void buildPath()
133     {
134         _solver.buildPath();
135     }

136     
137     
138     ///
<summary>
139     ///
directly gets the point for the current spline type with no lookup table to adjust for constant speed
140     ///
</summary>
141     
private Vector3 getPoint( float t )
142     {
143         
return _solver.getPoint( t );
144     }

145
146     
147     ///
<summary>
148     ///
returns the point that corresponds to the given t where t >= 0 and t <= 1 making sure that the
149     ///
path is traversed at a constant speed.
150     ///
</summary>
151     
public Vector3 getPointOnPath( float t )
152     {
153         
// if the path is closed, we will allow t to wrap. if is not we need to clamp t
154         
if( t < 0 || t > 1 )
155         {
156             
if( isClosed )
157             {
158                 
if( t < 0 )
159                     t +=
1;
160                 
else
161                     t -=
1;
162             }
163             
else
164             {
165                 t = Mathf.Clamp01( t );
166             }
167         }
168         
169         
return _solver.getPointOnPath( t );
170     }

171
172     
173     ///
<summary>
174     ///
closes the path adding a new node at the end that is equal to the start node if it isn't already equal
175     ///
</summary>
176     
public void closePath()
177     {
178         
// dont let this get closed twice!
179         
if( isClosed )
180             
return;
181         
182         isClosed =
true;
183         _solver.closePath();
184     }

185     
186     
187     ///
<summary>
188     ///
reverses the order of the nodes
189     ///
</summary>
190     
public void reverseNodes()
191     {
192         
if( !_isReversed )
193         {
194             _solver.reverseNodes();
195             _isReversed =
true;
196         }
197     }

198     
199     
200     ///
<summary>
201     ///
unreverses the order of the nodes if they were reversed
202     ///
</summary>
203     
public void unreverseNodes()
204     {
205         
if( _isReversed )
206         {
207             _solver.reverseNodes();
208             _isReversed =
false;
209         }
210     }
211     
212     
213     
public void drawGizmos( float resolution )
214     {
215         _solver.drawGizmos();
216         
217         
var previousPoint = _solver.getPoint( 0 );
218         
219         resolution *= _solver.nodes.Count;
220         
for( var i = 1; i <= resolution; i++ )
221         {
222             
var t = (float)i / resolution;
223             
var currentPoint = _solver.getPoint( t );
224             Gizmos.DrawLine( currentPoint, previousPoint );
225             previousPoint = currentPoint;
226         }
227     }

228     
229     
230     ///
<summary>
231     ///
helper for drawing gizmos in the editor
232     ///
</summary>
233     
public static void drawGizmos( Vector3[] path, float resolution = 50 )
234     {
235         
// horribly inefficient but it only runs in the editor
236         
var spline = new GoSpline( path );
237         spline.drawGizmos( resolution );
238     }
239
240 }



Trò chơi Angry Birds trong UNITY Engine 31.649 lượt xem

Gõ tìm kiếm nhanh...